unit OvladaniGameForm;

{$mode objfpc}{$H+}

interface

uses
  Classes, gameobjects, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  StdCtrls, Grids, MMsystem;

type
  TTetris = class(TGraphicControl)

  public
    constructor Create(AOwner: TComponent; p: TPlayer; lefts, bottoms,leftsn,bottomsn: integer);
  protected
    procedure Paint; override;
    procedure DrawSquare(x: integer; y: integer; z: integer);
  private
    Sleft: integer;
    Sbottom: integer;
    Nleft:Integer;
    Nbottom:integer;
    player: TPlayer;
    backgroundImage: TBitmap;
    chunkImage: TBitmap;

  end;




type

  { TGameForm }

  TGameForm = class(TForm)
    AvatarFrame1: TImage;
    AvatarFrame2: TImage;
    AvatarName1: TLabel;
    AvatarName2: TLabel;
    adcv: TImage;
    HPLabelRight: TLabel;
    Image1: TImage;
    Image10: TImage;
    Image12: TImage;
    Image2: TImage;
    Image3: TImage;
    Image4: TImage;
    Image5: TImage;
    Image6: TImage;
    Image7: TImage;
    Image8: TImage;
    Label1: TLabel;
    Label2: TLabel;
    HPLabelLeft: TLabel;
    RightArmorAmount: TLabel;
    LeftArmorAmount: TLabel;
    RightArmorLbl: TLabel;
    LeftArmorLbl1: TLabel;
    MMana1: TLabel;
    MMana2: TLabel;
    Slash3: TLabel;
    Slash4: TLabel;
    StanceADC: TImage;
    StanceHeal: TImage;
    StanceMage: TImage;
    StanceTank: TImage;
    StanceButton1: TButton;
    StanceButton2: TButton;
    CMana1: TLabel;
    CMana2: TLabel;
    p2picStance: TImage;
    p1picstance: TImage;
    tankv: TImage;
    healv: TImage;
    magv: TImage;
    picbackg: TImage;
    loseq: TLabel;
    P1linecount: TLabel;
    RTurnLeft: TButton;
    RTurnRight: TButton;
    LTurnLeft: TButton;
    LTurnRight: TButton;
    RSpawnButton: TButton;
    RLeftButton: TButton;
    RRightButton: TButton;
    RDownButton: TButton;
    RightButton: TButton;
    LeftButton: TButton;
    DownButton: TButton;
    SpawButton: TButton;

    CurrentHp2: TLabel;
    MaxHp1: TLabel;
    MaxHp2: TLabel;
    Slash1: TLabel;
    CurrentHp1: TLabel;
    Slash2: TLabel;
    t1pad: TTimer;
    t2pad: TTimer;



    procedure FormDeactivate(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure Image1Click(Sender: TObject);
    procedure p2picStanceClick(Sender: TObject);
    procedure picbackgClick(Sender: TObject);
    procedure StanceButton1Click(Sender: TObject);
    procedure loosecond(pll, plw: tplayer);
    procedure changeblock(ps:Tplayer);
    procedure dospell(pl: TPlayer);
    procedure LTurnLeftClick(Sender: TObject);
    procedure LTurnRightClick(Sender: TObject);
    procedure DownButtonClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure avatpic(pl: Tplayer);
    procedure LeftButtonClick(Sender: TObject);
    procedure RDownButtonClick(Sender: TObject);
    procedure RightButtonClick(Sender: TObject);
    procedure RLeftButtonClick(Sender: TObject);
    procedure RRightButtonClick(Sender: TObject);
    procedure RSpawnButtonClick(Sender: TObject);
    procedure RTurnLeftClick(Sender: TObject);
    procedure RTurnRightClick(Sender: TObject);
    procedure SpawButtonClick(Sender: TObject);
    procedure SpawnChunk(ps: Tplayer);
    procedure clearline1(ps: Tplayer);
    procedure StanceButton2Click(Sender: TObject);
    procedure p1picstanceClick(Sender: TObject);
    procedure t1padTimer(Sender: TObject);
    procedure t2padTimer(Sender: TObject);

    procedure TocLeft(ps: Tplayer);
    procedure TocRight(ps: Tplayer);
  private
    { private declarations }
    T: TTetris;
    P: TTetris;

     lost: Boolean;   //kontroluje prohru a tedy i funkcnost tlacitek
  public
    { public declarations }
    player1, player2, player3, pLoser, pWinner: TPlayer;
    PL1AV, PL2AV: integer;   //pomocne promenne pro prenos indexu vybraneho avatara z vyberoveho formulare

  end;

var
  GameForm: TGameForm;

implementation

{ TGameForm }

procedure TGameForm.FormCreate(Sender: TObject);

begin

end;

procedure TGameForm.TocLeft(ps: Tplayer);  //otoceni chunku doleva//
var
  x, y: integer;
var
  helpchunk: array [1..CHUNK_WIDTH, 1..CHUNK_HEIGHT] of boolean;   //pomocne pole pro kopirovani chunku pred otocenim, aby se zamezilo vzajemnemu ovlivnovani prepsanych a neprepsanych ctvercu: totez jako hra Life//

begin
  if not lost then begin

  if ps.ChunkStyle <> 1 then  //chunkstyle 1 odpovida krychli, ta se nema otacet//
  begin
    // do helpchunku se zkopiruje otoceny hracuv chunk //
    for x := 1 to CHUNK_WIDTH do
    begin
      for y := 1 to CHUNK_HEIGHT do
      begin
        helpchunk[y, (CHUNK_HEIGHT - x + 1)] := ps.FieldCHUNK[x, y];
      end;
    end;
    // helpchunk se zkopiruje do hracova chunku //
    for x := 1 to CHUNK_WIDTH do
    begin
      for y := 1 to CHUNK_HEIGHT do
      begin

        ps.FieldCHUNK[x, y] := helpchunk[x, y];
      end;
    end;
    T.Invalidate;
  end;
end;
 end;
procedure TGameForm.TocRight(ps: Tplayer); //analogie tocleft, jen na druhou stranu//

var
  x, y: integer;
var
  helpchunk: array [1..CHUNK_WIDTH, 1..CHUNK_HEIGHT] of boolean;

begin
  if not lost then
  begin
  if ps.ChunkStyle <> 1 then
  begin
    // do helpchunku se zkopiruje otoceny hracuv chunk //
    for x := 1 to CHUNK_WIDTH do
    begin
      for y := 1 to CHUNK_HEIGHT do
      begin
        helpchunk[(CHUNK_HEIGHT - y + 1), x] := ps.FieldCHUNK[x, y];
      end;
    end;
    // helpchunk se zkopiruje do hracova chunku //
    for x := 1 to CHUNK_WIDTH do
    begin
      for y := 1 to CHUNK_HEIGHT do
      begin
        ps.FieldCHUNK[x, y] := helpchunk[x, y];
      end;
    end;
    T.Invalidate;
  end;

  end;
end;

procedure TGameForm.changeblock(ps:TPlayer);    //zde se z pristiho chunku prepisuje do pomocneho//
begin
      case ps.NEXTBLOCK of
    0:
    begin //lajna
      Ps.ChunkStyleN := 0;
      ps.FieldpChunk[2, 1] := True;
      ps.FieldpChunk[2, 2] := True;
      ps.FieldpChunk[2, 3] := True;
      ps.diffblN := 1;
    end;
    1:
    begin //ctverec
      Ps.ChunkStyleN := 1;
      ps.FieldpChunk[3, 2] := True;
      ps.FieldpChunk[3, 3] := True;
      ps.FieldpChunk[2, 2] := True;
      ps.FieldpChunk[2, 3] := True;
      ps.diffblN := 1;
    end;

    2:
    begin          //Lko
      Ps.ChunkStyleN := 2;
      ps.FieldpChunk[2, 3] := True;
      ps.FieldpChunk[2, 1] := True;
      ps.FieldpChunk[2, 2] := True;
      ps.FieldpChunk[1, 3] := True;
      ps.diffblN := 2;
    end;

    3:
    begin          //Lko
      Ps.ChunkStyleN := 2;
      ps.FieldpChunk[2, 3] := True;
      ps.FieldpChunk[2, 1] := True;
      ps.FieldpChunk[2, 2] := True;
      ps.FieldpChunk[1, 1] := True;
      ps.diffbln := 2;
    end;

    4:
    begin              //Pyramida
      Ps.ChunkStyleN := 4;  //!!!!!!
      ps.FieldpChunk[2, 1] := True;
      ps.FieldpChunk[2, 2] := True;
      ps.FieldpChunk[2, 3] := True;
      ps.FieldpChunk[1, 2] := True;
      ps.diffbln := 2;
    end;
    5:
    begin    // Kekel
      Ps.ChunkStyleN := 3;//!!!!!!
      ps.FieldpChunk[1, 1] := True;
      ps.FieldpChunk[2, 1] := True;
      ps.FieldpChunk[3, 1] := True;
      ps.FieldpChunk[1, 3] := True;
      ps.FieldpChunk[2, 3] := True;
      ps.FieldpChunk[3, 3] := True;

      ps.FieldpChunk[2, 2] := True;
      ps.diffbln := 3;
    end;
  end;
      t1pad.Enabled:=true;
      t2pad.Enabled:=true;
end;

procedure TGameForm.dospell(pl: TPlayer);
  var prhp :integer;
begin

  case pl.stance of
    A:
    begin
      PlaySound('SoundDamage', 0, SND_ASYNC);
      pl.attack := (pl.diffbl) * (pl.linedes) + (pl.ADR);
      if pl.avt = 4 then
        pl.CurrentMa := pl.CurrentMa + 5
      else
        pl.CurrentMa := pl.CurrentMa + 1;
      if player1.Block - player2.Attack < 0 then
      begin
        player1.CurrentHP := player1.CurrentHP - player2.Attack + player1.Block;
        player1.Block := 0;
      end

      else
        player1.Block := player1.Block - player2.Attack;

      if player2.Block - player1.Attack < 0 then
      begin
        player2.CurrentHP := player2.CurrentHP - player1.Attack + player2.Block;
        player2.Block := 0;
      end
      else
        player2.Block := player2.Block - player1.Attack;
      pl.Attack := 0;

    end;
    D:
    begin
      PlaySound('SoundShield', 0, SND_ASYNC);
      pl.Block := (pl.diffbl) * (pl.linedes) + (pl.ArmorR);
      if pl.avt = 4 then
        pl.CurrentMa := pl.CurrentMa + 5
      else
        pl.CurrentMa := pl.CurrentMa + 1;

    end;
    H:
    begin
      PlaySound('SoundHeal', 0, SND_ASYNC);
      if pl.avt = 3 then
      begin

        pl.CurrentHP := pl.CurrentHP + ((pl.diffbl) * (pl.linedes) + (pl.CurrentMa) + pl.HealR);
        if pl.CurrentHP > pl.MaxHP then
          pl.CurrentHP := pl.MaxHP;
        pl.CurrentMa := 0;

      end
      else
      begin
        prhp:= pl.CurrentHP + ((pl.diffbl) * (pl.linedes) +
          (((pl.CurrentMa) div 10) * 10) + pl.HealR);
        if prhp>pl.currentHp then
        pl.CurrentHP := prhp
        else pl.CurrentHP:=pl.CurrentHP;
        if pl.CurrentHP > pl.MaxHP then
          pl.CurrentHP := pl.MaxHP;
        case (pl.CurrentMa) div 10 of
          1: pl.CurrentMa := pl.CurrentMa - 10;
          2: pl.CurrentMa := pl.CurrentMa - 20;
          3: pl.CurrentMa := pl.CurrentMa - 30;
          4: pl.CurrentMa := pl.CurrentMa - 40;
        end;
      end;
    end;

    M:
    begin

      begin
        if pl.avt = 4 then
        begin
          case pl.CurrentMa div 10 of
            1:
            begin
              randomize;
              if (pl.diffbl) * (pl.linedes) <= 4 then
                pl.NEXTBLOCK := 2 + random(3);
              if (pl.diffbl) * (pl.linedes) = 6 then
                pl.NEXTBLOCK := random(1);
              pl.CurrentMa := pl.CurrentMa - 10;
            end;
            2:
            begin
              randomize;
              if (pl.diffbl) * (pl.linedes) <= 4 then
              begin
                if pl = player1 then
                  player2.NEXTBLOCK := 2 + random(3)
                else
                  player1.NEXTBLOCK := 2 + random(3);

              end;
              if (pl.diffbl) * (pl.linedes) = 6 then
              begin
                if pl = player1 then
                  player2.NEXTBLOCK := 5
                else
                  player1.NEXTBLOCK := 5;
              end;
              pl.CurrentMa := pl.CurrentMa - 20;
            end;
            3:
            begin
              randomize;
              if (pl.diffbl) * (pl.linedes) <= 4 then
              begin
                if pl = player1 then
                  player2.NEXTBLOCK := 2 + random(3)
                else
                  player1.NEXTBLOCK := 2 + random(3);
              end;
              if (pl.diffbl) * (pl.linedes) = 6 then
              begin
                if pl = player1 then
                  player2.NEXTBLOCK := 5
                else
                  player1.NEXTBLOCK := 5;
              end;
              pl.CurrentMa := pl.CurrentMa - 20;
            end;
            4:
            begin
              pl.spellgo := True;
              player3 := Tplayer.Create;

              pl.CurrentMa := pl.CurrentMa - 40;
            end;

            else
            begin
              if pl.CurrentMa > 40 then
              begin
                pl.CurrentMa := 40;
                dospell(pl);
              end;
            end;
          end;
        end
        else
          case pl.CurrentMa div 10 of  //heal magic
            1:
            begin
              randomize;
              if (pl.diffbl) * (pl.linedes) <= 4 then
                pl.NEXTBLOCK := 5;
              if (pl.diffbl) * (pl.linedes) = 6 then
                pl.NEXTBLOCK := 2 + random(3);
              pl.CurrentMa := pl.CurrentMa - 10;
            end;
            2:
            begin
              randomize;
              if (pl.diffbl) * (pl.linedes) <= 4 then
              begin
                if pl = player1 then
                  player2.NEXTBLOCK := random(1)
                else
                  player1.NEXTBLOCK := random(1);
              end;
              if (pl.diffbl) * (pl.linedes) = 6 then
              begin
                if pl = player1 then
                  player2.NEXTBLOCK := 2 + random(3)
                else
                  player1.NEXTBLOCK := 2 + random(3);
              end;
              pl.CurrentMa := pl.CurrentMa - 20;
            end;
            3:
            begin
              randomize;
              if (pl.diffbl) * (pl.linedes) <= 4 then
              begin
                if pl = player1 then
                  player2.NEXTBLOCK := random(1)
                else
                  player1.NEXTBLOCK := random(1);
              end;
              if (pl.diffbl) * (pl.linedes) = 6 then
              begin
                if pl = player1 then
                  player2.NEXTBLOCK := 2 + random(3)
                else
                  player1.NEXTBLOCK := 2 + random(3);
              end;
              pl.CurrentMa := pl.CurrentMa - 20;
            end;
            4:
            begin
              randomize;
              if (pl.diffbl) * (pl.linedes) <= 4 then
              begin
                if pl = player1 then
                  player2.NEXTBLOCK := random(1)
                else
                  player1.NEXTBLOCK := random(1);
              end;
              if (pl.diffbl) * (pl.linedes) = 6 then
              begin
                if pl = player1 then
                  player2.NEXTBLOCK := 2 + random(3)
                else
                  player1.NEXTBLOCK := 2 + random(3);
              end;
              pl.CurrentMa := pl.CurrentMa - 20;
            end;


            else
            begin
              if pl.CurrentMa > 40 then
              begin
                pl.CurrentMa := 40;
                dospell(pl);
              end;


            end;

          end;
        t1pad.Enabled:=false;
      changeblock(player1);
      t2pad.Enabled:=false;
      changeblock(player2);

      end;

      PlaySound('SoundMagic', 0, SND_ASYNC);
    end;

  end;
  begin
    if pl.CurrentMa > 40 then
    begin
      pl.CurrentMa := 40;

    end;
  end;
  CurrentHp1.Caption := IntToStr(player1.CurrentHP);
  CurrentHp2.Caption := IntToStr(player2.CurrentHP);
  CMana1.Caption := IntToStr(player1.CurrentMa);
  CMana2.Caption := IntToStr(player2.CurrentMa);
  LeftArmorAmount.Caption := IntToStr(player1.Block);
  RightArmorAmount.Caption := IntToStr(player2.Block);
  // looose reeeeal cond <0
  { if player1.CurrentHP <= 0 then
  begin
    lost := true;
    loosecond(player1, player2);
     PlaySound('SoundQuestfail', 0, SND_ASYNC);
    loseq.Caption := (pWinner.Name + ' is victorious.' + pLoser.Name +
      ' is a scrubby looser.(press cross to exit)');
    t1pad.Enabled := False;

    t2pad.Enabled := False;
    DownButton.enabled:=False;
    LeftButton.enabled:=False;
    RightButton.enabled:=False;
    RSpawnButton.enabled:=False;
    RLeftButton.enabled:=False;
    RRightButton.enabled:=False;
    RDownButton.enabled:=False;
    StanceButton1.enabled:=False;
    StanceButton2.Enabled:=false;
    LTurnLeft.Enabled:=False;
    LTurnRight.Enabled:=False;
    RTurnLeft.Enabled:=False;
    RTurnRight.Enabled:=False;

    player1.ruin;
    player2.ruin;

  end;
  if player2.CurrentHP <= 0 then
  begin
    loosecond(player2, player1);
     PlaySound('SoundQuestfail', 0, SND_ASYNC);
    loseq.Caption := (pWinner.Name + ' is victorious.' + pLoser.Name +
      ' is a scrubby looser.(press cross to exit)');
    t1pad.Enabled := False;
    t2pad.Enabled := False;
    DownButton.enabled:=False;
    LeftButton.enabled:=False;
    RightButton.enabled:=False;
    RSpawnButton.enabled:=False;
    RLeftButton.enabled:=False;
    RRightButton.enabled:=False;
    RDownButton.enabled:=False;
    StanceButton1.enabled:=False;
    StanceButton2.Enabled:=false;
    LTurnLeft.Enabled:=False;
    LTurnRight.Enabled:=False;
    RTurnLeft.Enabled:=False;
    RTurnRight.Enabled:=False;
     player1.ruin;
  player2.ruin;
  end;
        }
end;

procedure tgameform.loosecond(pll, plw: tplayer);
begin
  pLoser := pll;
  pWinner := plw;

end;

procedure Tgameform.clearline1(ps: Tplayer);    //metoda, ktera se zavola po dopadu chunku v tetrisu//
var
  b, c, y, x: integer;
var
  a: boolean;
begin
  ps.linedes := 0;
  for y := 2 to ps.GetHeight do        //tato cast projizdi rady od zdola nahoru, a hleda, ktera je plna//
  begin
    a := True;
    for x := 2 to ps.Getwidth do
    begin
      if a then
        if ps.FieldBoard[x, y] = False then
          a := False;
    end;
    if a = True then                //tato cast vyprazdnuje radu, ktera byla zjistena jako plna//
    begin
      for x := 2 to ps.Getwidth do
      begin
        ps.FieldBoard[x, y] := False;
      end;
      Inc(ps.Linecount);
      Inc(ps.linedes);
      if ps.sickness > 0 then
      begin
        Dec(ps.sickness);               //tato cast zmensi sickness o jedna, ale nikdy ne do zapornych hodnot//
        ps.ADR := ps.ADR + (ps.ADR div 10) * (10 - (ps.sickness));
        ps.ArmorR := ps.ArmorR + (ps.ArmorR div 10) * (10 - (ps.sickness));
        ps.HealR := ps.HealR + (ps.HealR div 10) * (10 - (ps.sickness));
      end;

      c := 1;
      P1linecount.Caption := IntToStr(player1.Linecount);     //zde se zrychluji timery//
      if Player1.Linecount mod 10 = 0 then
        t1pad.interval := ((t1pad.interval * 9) div 10);
      //Plinecount.Caption:=IntTostr(player1.Linecount);
      if Player2.Linecount mod 10 = 0 then
        t1pad.interval := ((t2pad.interval * 9) div 10);
    end;
  end;
  if c = 1 then                                  //provede se aktivni schopnost, pokud byla alespon jedna rada doplnena
    dospell(ps);
  for b := 1 to 3 do                    //v teto casti spadnou vrchni rady o jedna dolu
  begin
    for y := 2 to ps.GetHeight - 1 do
    begin
      a := False;
      for x := 2 to ps.Getwidth do
      begin
        if a = False then
          if ps.FieldBoard[x, y] = True then
            a := True;
      end;
      if a = False then
      begin
        for x := 2 to ps.Getwidth do
        begin
          ps.FieldBoard[x, y] := ps.FieldBoard[x, y + 1];
          ps.FieldBoard[x, y + 1] := False;
        end;
      end;
    end;
  end;

end;

procedure TGameForm.StanceButton2Click(Sender: TObject);
var
  x, y: integer;
begin
  if not lost then
  begin
  begin
    if player2.spellgo then               //pokud ma byt aktvini nejvyssi uroven schopnosti magie, provede se prehozeni poli//
    begin
      for x := 1 to 9 do
        for y := 1 to 22 do
          player3.fieldboard[x, y] := player1.FieldBoard[x, y];
      for x := 1 to 9 do
        for y := 1 to 22 do
          player1.fieldboard[x, y] := player2.FieldBoard[x, y];
      for x := 1 to 9 do
        for y := 1 to 22 do
          player2.fieldboard[x, y] := player3.FieldBoard[x, y];
      player2.spellgo := False;
    end;
    p.Invalidate;
    t.invalidate;
    Player2.CHANGESTANCE;                //zde se provadi zmena aktivni schopnosti//
    case Player2.Stance of              //a prehazuji obrazky//
      A: p2picstance.Picture := StanceADC.Picture;
      D: p2picstance.Picture := StanceTank.Picture;
      H: p2picstance.Picture := StanceHeal.Picture;
      M: p2picstance.Picture := StanceMage.Picture;

    end;
  end;
  end;

end;

procedure TGameForm.p1picstanceClick(Sender: TObject);
begin

end;

procedure TGameForm.DownButtonClick(Sender: TObject);
begin
  if not lost then
  begin
  if player1.CanMoveTo(1 + player1.ChunkshiftX, 1 + player1.ChunkshiftY - 1) then       //pokud je prostor volny, chunk spadne v hernim poli o jedna dolu, vlastne jen tim, ze se snizi Y-ovy chunkshift, cili vzdalenost chunku od spodni hranice hraciho pole
  begin
    player1.ChunkShiftY := player1.ChunkShiftY - 1;
  end
  else
  begin          //neni-li prostor pro posun, chunk se stane soucasti herniho pole, zkusi se smazani doplnene rady a hraci je vytvoren novy chunk//
    player1.CopyChunkToBoard;
    clearline1(player1);

    SpawnChunk(player1);
  end;
  T.Invalidate;
  end;

end;

procedure TGameForm.t1padTimer(Sender: TObject);
var
  a: TObject;
begin
  DownButtonClick(a);
  if player1.CurrentHP <= 0 then
  begin
    lost := true;
    PlaySound('SoundQuestfail', 0, SND_ASYNC);
    loosecond(player1, player2);
    loseq.Caption := (pWinner.Name + ' is victorious.' + pLoser.Name +
      ' lost his life.');
    t1pad.Enabled := False;
    t2pad.Enabled := False;
    player1.ruin;
    player2.ruin;
  end;
  if player2.CurrentHP <= 0 then
  begin
    lost := true;
    PlaySound('SoundQuestfail', 0, SND_ASYNC);
    loosecond(player2, player1);
    loseq.Caption := (pWinner.Name + ' is victorious.' + pLoser.Name +
      ' lost his life.');
    t1pad.Enabled := False;
    t2pad.Enabled := False;
    player1.ruin;
    player2.ruin;
  end;
   //if Player1.Linecount mod 10 =0 then t1pad.interval:=(t1pad.interval*0.9);
end;


procedure TGameForm.LTurnLeftClick(Sender: TObject);
begin
  if player1.cantocleftto then
    TocLeft(player1);
end;


procedure TGameForm.StanceButton1Click(Sender: TObject);    //analogie  StanceButton2Click pro druheho hrace
var
  x, y: integer;
  begin
if not lost then

begin
  if player1.spellgo then
  begin
    for x := 1 to 9 do
      for y := 1 to 22 do
        player3.fieldboard[x, y] := player1.FieldBoard[x, y];
    for x := 1 to 9 do
      for y := 1 to 22 do
        player1.fieldboard[x, y] := player2.FieldBoard[x, y];
    for x := 1 to 9 do
      for y := 1 to 22 do
        player2.fieldboard[x, y] := player3.FieldBoard[x, y];
    player1.spellgo := False;
  end;
  T.INVALIDATE;
  P.INVALIDATE;
  Player1.CHANGESTANCE;
  case Player1.Stance of

    A: p1picstance.Picture := StanceADC.Picture;
    D: p1picstance.Picture := StanceTank.Picture;
    H: p1picstance.Picture := StanceHeal.Picture;
    M: p1picstance.Picture := StanceMage.Picture;

  end;
end;
 end;


procedure TGameForm.FormDeactivate(Sender: TObject);
begin
  Application.Terminate;
end;

procedure TGameForm.FormResize(Sender: TObject);
begin

end;

procedure TGameForm.Image1Click(Sender: TObject);
begin

end;

procedure TGameForm.p2picStanceClick(Sender: TObject);
begin

end;

procedure TGameForm.picbackgClick(Sender: TObject);
begin

end;




procedure TGameForm.LTurnRightClick(Sender: TObject);
begin
  if player1.cantocrightto then
    Tocright(player1);
end;


procedure TGameForm.SpawnChunk(ps: Tplayer);
var
  chunk, CHUNKNEXT, x, y, x1, y1: integer;
begin

   ps.fieldchunk := ps.fieldpchunk;
   ps.chunkstyle := ps.ChunkStyleN;     // tyto tri metody prenaseji udaje z chunku, ktery byl drive nastaven jako pristi do toho, ktery je soucasny
   ps.diffbl := ps.diffbln;
  for x := 1 to CHUNK_WIDTH do
  begin
    for  y := 1 to CHUNK_HEIGHT do        //zde se vycisti pristi chunk//
    begin
      ps.FieldNextCHUNK[x, y] := False;
    end;
  end;

  randomize;
//   PS.NEXTBLOCK := random(6);
  CHUNKNEXT := random(6);       //zde se urci, jaky bude pristi chunk//
  case chunkNEXT of
    0:
    begin //lajna
      Ps.ChunkStyleN := 0;     //chunkstyle slouzi k vyhodnocovani otaceni//
      ps.FieldNEXTChunk[2, 1] := True;
      ps.FieldNEXTChunk[2, 2] := True;
      ps.FieldNEXTChunk[2, 3] := True;
      ps.diffblN := 1;         //diffblN slouzi k vypoctum ve schopnosti magie//
      ps.NEXTBLOCK:=0;
    end;
    1:
    begin //ctverec
      Ps.ChunkStyleN := 1;
      ps.FieldNEXTChunk[3, 2] := True;
      ps.FieldNEXTChunk[3, 3] := True;
      ps.FieldNEXTChunk[2, 2] := True;
      ps.FieldNEXTChunk[2, 3] := True;
      ps.diffblN := 1;
       ps.NEXTBLOCK:=1;
    end;

    2:
    begin          //Lko
      Ps.ChunkStyleN := 2;
      ps.FieldNEXTChunk[2, 3] := True;
      ps.FieldNEXTChunk[2, 1] := True;
      ps.FieldNEXTChunk[2, 2] := True;
      ps.FieldNEXTChunk[1, 3] := True;
      ps.diffblN := 2;
      ps.NEXTBLOCK:=2;
    end;

    3:
    begin          //Lko
      Ps.ChunkStyleN := 2;
      ps.FieldNEXTChunk[2, 3] := True;
      ps.FieldNEXTChunk[2, 1] := True;
      ps.FieldNEXTChunk[2, 2] := True;
      ps.FieldNEXTChunk[1, 1] := True;
      ps.diffbln := 2;
      ps.NEXTBLOCK:=3;
    end;

    4:
    begin              //Pyramida
      Ps.ChunkStyleN := 4;  //!!!!!!
      ps.FieldNEXTChunk[2, 1] := True;
      ps.FieldNEXTChunk[2, 2] := True;
      ps.FieldNEXTChunk[2, 3] := True;
      ps.FieldNEXTChunk[1, 2] := True;
      ps.diffbln := 2;
      ps.NEXTBLOCK:=4;
    end;
    5:
    begin    // Kekel
      Ps.ChunkStyleN := 3;//!!!!!!
      ps.FieldNEXTChunk[1, 1] := True;
      ps.FieldNEXTChunk[2, 1] := True;
      ps.FieldNEXTChunk[3, 1] := True;
      ps.FieldNEXTChunk[1, 3] := True;
      ps.FieldNEXTChunk[2, 3] := True;
      ps.FieldNEXTChunk[3, 3] := True;

      ps.FieldNEXTChunk[2, 2] := True;
      ps.NEXTBLOCK:=5;
      ps.diffbln := 3;
    end;
  end;
    ps.fieldpchunk:=ps.FieldNextCHUNK;     //pristi chunk se zkopiruje do soucasneho//

  if not ps.CanMoveTo(3, 18) then       //zde se vyhodnocuje, kdy byl tetris prohran//
  begin

    for x1 := 2 to ps.GetWidth do
      for y1 := 2 to ps.GetHeight do
      begin
        ps.fieldboard[x1, y1] := False;  //tetris se vycisti//
      end;
    //for x:=0 to 3 do
    //for y:=0 to 3 do
    //ps.FieldChunk [x,y] := false;
    PlaySound('SoundSickness', 0, SND_ASYNC);        //zde se aplikuje sickness//
    ps.sickness := 10;
    ps.CurrentHP := ps.CurrentHP div 10;
    ps.ADR := ps.ADR div 10;
    ps.ArmorR := ps.ArmorR div 10;
    ps.HealR := ps.HealR div 10;
    SpawnChunk(ps);
    CurrentHp1.Caption := IntToStr(player1.CurrentHP);
    CurrentHp2.Caption := IntToStr(player2.CurrentHP);
  end;
  ps.ChunkShiftX := 3;
  ps.ChunkShiftY := 18;

    t1pad.Enabled := True;
  t2pad.Enabled := True;


end;

procedure Tgameform.avatpic(pl: Tplayer);     //tato metoda prirazuje obrazky podle vyberu avatara//
begin
  if pl = player1 then
  begin
    case pl.avt of
      1:
      begin
        AvatarFrame1.Picture := adcv.Picture;
        p1picstance.Picture := StanceADC.Picture;
      end;
      2:
      begin
        AvatarFrame1.Picture := tankv.Picture;
        p1picstance.Picture := StanceADC.Picture;
      end;
      3:
      begin
        AvatarFrame1.Picture := healv.Picture;
        p1picstance.Picture := StanceADC.Picture;
      end;
      4:
      begin
        AvatarFrame1.Picture := magv.Picture;
        p1picstance.Picture := StanceADC.Picture;
      end;
    end;
  end
  else
  begin
    case pl.avt of
      1:
      begin
        AvatarFrame2.Picture := adcv.Picture;
        p2picstance.Picture := StanceADC.Picture;
      end;
      2:
      begin
        AvatarFrame2.Picture := tankv.Picture;
        p2picstance.Picture := StanceADC.Picture;
      end;
      3:
      begin
        AvatarFrame2.Picture := healv.Picture;
        p2picstance.Picture := StanceADC.Picture;
      end;
      4:
      begin
        AvatarFrame2.Picture := magv.Picture;
        p2picstance.Picture := StanceADC.Picture;
      end;
    end;

  end;

end;


procedure TGameForm.FormShow(Sender: TObject);   //zahajuje hru, kdyz se ukauze gameform//

begin
  player1 := TPlayer.Create;       //vytvori instance hracu //
  player2 := TPlayer.Create;
  player1.Initialize(PL1AV);
  avatpic(player1);         //priradi obrazky hracum  //
  if pl1av = pl2av then                //zde se resi stejnojmennost avataru, je-li vybran stejny avatar, zavola se pro druheho hrace prejmenovavaci metoda//
  begin
    player2.Initialize(PL2AV);
    player2.rename(PL2AV);
  end
  else player2.Initialize(PL2AV);
  avatpic(player2);
  AvatarName1.Caption := player1.Name;
  AvatarName2.Caption := player2.Name;              //zde se aktualizuji labely podle hodnot avataru//
  MaxHP1.Caption := IntToStr(player1.MaxHP);
  CurrentHP1.Caption := IntToStr(player1.CurrentHP);
  MaxHP2.Caption := IntToStr(player2.MaxHP);
  CurrentHP2.Caption := IntToStr(player2.CurrentHP);
  T := TTetris.Create(self, Player1, 010, 450,10,12);     //zde se vytvori graficke kontroly Tetris//
  T.parent := self;
  T.Top := 128;
  T.Left := 128;
  P := TTetris.Create(self, Player2, 800, 450,10,-5);
  P.parent := self;
  P.Top := 128;
  P.Left := 128;

end;

procedure TGameForm.LeftButtonClick(Sender: TObject);
begin
  if not lost then
  begin
  if (Player1.CanMoveTo(1 + player1.CHUNKSHIFTX - 1, 1 + player1.CHUNKSHIFTY)) then
  begin
    player1.ChunkShiftX := player1.ChunkShiftX - 1;
    T.Invalidate;
  end;
  end;
end;

procedure TGameForm.RDownButtonClick(Sender: TObject);

begin
  if not lost then
  begin
  if player2.CanMoveTo(1 + player2.ChunkshiftX, 1 + player2.ChunkshiftY - 1) then
  begin
    player2.ChunkShiftY := player2.ChunkShiftY - 1;
  end
  else
  begin
    player2.CopyChunkToBoard;
    clearline1(player2);
    SpawnChunk(player2);
  end;

  T.Invalidate;
  end;

end;

procedure TGameForm.t2padTimer(Sender: TObject);
var
  a: TObject;
begin
  if not lost then RDownButtonClick(a);
end;

procedure TGameForm.RightButtonClick(Sender: TObject);
begin
  if not lost then
  begin
  if Player1.CanMoveTo(1 + player1.CHUNKSHIFTX + 1, 1 + player1.CHUNKSHIFTY) then
  begin
    player1.ChunkShiftX := player1.ChunkShiftX + 1;
    T.Invalidate;
  end;
  end;
end;

procedure TGameForm.RLeftButtonClick(Sender: TObject);
begin
  if not lost then
  begin
  if Player2.CanMoveTo(1 + player2.CHUNKSHIFTX - 1, 1 + player2.CHUNKSHIFTY) then
  begin
    player2.ChunkShiftX := player2.ChunkShiftX - 1;
    T.Invalidate;
  end;
  end;
end;



procedure TGameForm.RRightButtonClick(Sender: TObject);
begin
  if not lost then
  begin
  if Player2.CanMoveTo(1 + player2.CHUNKSHIFTX + 1, 1 + player2.CHUNKSHIFTY) then
  begin
    player2.ChunkShiftX := player2.ChunkShiftX + 1;
    T.Invalidate;
  end;
  end;
end;



procedure TGameForm.RSpawnButtonClick(Sender: TObject);
begin
  if not lost then
  begin
  SpawnChunk(Player2);
  T.Invalidate;
  end;
end;

procedure TGameForm.RTurnLeftClick(Sender: TObject);
begin
  if not lost then
  begin
  if player2.cantocleftto then
    TocLeft(player2);
  end;
end;

procedure TGameForm.RTurnRightClick(Sender: TObject);
begin
  if not lost then
  begin
  if player2.cantocrightto then
    TocRight(player2);
  end;
end;

procedure TGameForm.SpawButtonClick(Sender: TObject);
begin
  if not lost then
  begin
  SpawnChunk(Player1);
  T.Invalidate;
   end;
end;

constructor TTetris.Create(AOwner: TComponent; p: TPlayer; lefts, bottoms,leftsn,bottomsn: integer);  //konstruktor tetrisu//
begin

  inherited Create(AOwner);
  player := p;
  with GetControlClassDefaultSize do
 SetBounds(0, 0,6000, 6000);
 //SetInitialBounds(0, 0, 10000, 6000);
  backgroundImage := TBitmap.Create;
  //backgroundImage.LoadFromFile('D:\ProjectTetris\Grafika\Jpeg_1.bmp');
  backgroundImage.LoadFromFile('..\Grafika\Jpeg_1.bmp');     //zde se nahravaji obrazky, jake budou jednotlive ctverce mit, jsou pak pouzity jako atributy metody drawsquare//
  chunkImage := TBitmap.Create;
  //chunkImage.LoadFromFile('D:\ProjectTetris\Grafika\Jpeg_2.bmp');
  chunkImage.LoadFromFile('..\Grafika\Jpeg_2.bmp');
  Nleft:=leftsn;         //zde se prenaseji bezne souradnice a souradnice N//
  Nbottom:=bottomsn;
  Sleft := lefts;
  Sbottom := bottoms;
  Gameform.SpawnChunk(p);             //toto zajistuje, aby po vytvoreni kontroly zacaly padat bloky//
end;

procedure TTetris.DrawSquare(x: integer; y: integer; z: integer);  //kresli 1 ctverec graficke kontroly tetrisu//
//parametry x a y urcuji jeho souradnice v hernim poli, z urcuje, jestli kreslime padajici chunk, nebo nektery z pevnych ctvercu hraciho pole//
var

  SHIFT_LEFT, SHIFT_BOTTOM, SIZE: integer;   //Sleft a Sbottom jsou odkazy na levy dolni roh teto kontroly, cili urcuji, odkud se bude ctverec kreslit//
var
  corner_bottom, corner_left: integer;
begin
  SHIFT_LEFT := Sleft;
  SHIFT_BOTTOM := Sbottom;
  SIZE := 18;          //velikost. protoze je to ctverec, staci nam jedna strana//

  corner_left := SHIFT_LEFT + x * SIZE;          //+x*size zajistuje, ze az se tato metoda bude v cyklu volat, bude kazdy ctverec posunut prave o svoji velikost od toho predchoziho//
  corner_bottom := SHIFT_BOTTOM - (y * SIZE);                 // kdyby tam nebylo - ale +, kreslily by se bloky pod sebe//

  case z of
    0:                         //kreslime prazdny ctverec herniho pole//
    begin
      Canvas.Brush.Style := bsClear; //Transparent;
      Canvas.Rectangle(corner_left, corner_bottom, corner_left +
        SIZE - 1, corner_bottom - SIZE + 1);      //preddefinovane metody, parametry jsou rohy obdelniku//
    end;
    1:                    //kreslime pevny ctverec herniho pole//
    begin
      Canvas.Brush.Color := clblue;
      Canvas.Brush.Style := bsSolid;
      //Canvas.Rectangle( corner_left, corner_bottom, corner_left + SIZE - 1, corner_bottom - SIZE + 1);
      Canvas.Draw(corner_left + 1, corner_bottom - SIZE + 1, backgroundimage);
    end;
    2:            //kreslime ctverec pohybliveho chunku v hernim poli//
    begin
      Canvas.Brush.Color := clred;
      Canvas.Brush.Style := bsSolid;
      Canvas.Draw(corner_left + 1, corner_bottom - SIZE + 1, chunkimage);
      //Canvas.Rectangle( corner_left, corner_bottom, corner_left + SIZE - 1, corner_bottom - SIZE + 1);
    end;
  end;

end;

procedure TTetris.Paint;      //zdedena metoda paint, zavola se vzdy po invalidate, prekresluje tetris, kdyz se zmeni//
var
  x1, y1: integer;
begin
  inherited Paint;
  for x1 := 2 to Player.GetWidth do     //prvni rada se nevykresluje, nechavame ji plnou, aby chunky nepropadly prilis dolu//
    for y1 := 2 to Player.GetHeight do        //prochazime hracovo herni pole//
    begin
      if (Player.FieldBoard[x1, y1]) then
      begin
        DrawSquare(x1, y1, 1); //je-li ctverec plny//
      end
      else
      begin
        DrawSquare(x1, y1, 0);     //je-li prazdny//
      end;
    end;

  for x1 := 1 to CHUNK_WIDTH do    //prochazime hracuv chunk//
    for y1 := 1 to CHUNK_HEIGHT do
    begin
      if (Player.FieldChunk[x1, y1]) then
      begin
        DrawSquare(x1 + Player.ChunkShiftX, y1 + Player.ChunkShiftY, 2);        //kreslime sice do herniho pole, ale ptame se na plnost bloku v chunku, polohu chunku v poli udavaji chunkshifty (ktere se meni, kdyz hrac posouva blok)//
      end;
    end;
   for x1 := 1 to CHUNKwh do          //tato cast kresli zobrazeni nextchunku , k tomu slouzi sady souradnic N//
    for y1 := 1 to CHUNKwh do
    begin
      if (Player.FieldnextChunk[x1, y1]) then
      begin
        DrawSquare(x1+nbottom , y1+nleft , 2);
      end;
    end;
end;

{$R *.lfm}

end.
